package com.weilele.mvvm.utils.aria.download

import androidx.lifecycle.LifecycleOwner
import com.arialyy.aria.core.common.AbsNormalTarget
import com.arialyy.aria.core.config.DownloadConfig
import com.arialyy.aria.core.download.DownloadEntity
import com.arialyy.aria.core.download.DownloadTaskListener
import com.arialyy.aria.core.download.target.HttpBuilderTarget
import com.arialyy.aria.core.download.target.HttpNormalTarget
import com.arialyy.aria.core.inf.IEntity
import com.arialyy.aria.core.task.DownloadTask
import com.weilele.mvvm.base.helper.ILifecycleObserver
import com.weilele.mvvm.utils.aria.AriaHelper
import java.lang.Exception

object MvvmDownload {

    init {
        //保证所以操作调用前Aria 已经初始化完毕
        AriaHelper
    }

    /**
     * downloadTask
     */
    private val downloadTask by lazy { AriaHelper.download }

    /**
     * 下载参数配置
     */
    fun updateConfig(block: (DownloadConfig) -> Unit) {
        block.invoke(AriaHelper.aria.downloadConfig)
    }

    /**
     * 更新task
     */
    fun <Target : AbsNormalTarget<*>> updateTask(
        taskId: Long,
        block: (HttpNormalTarget) -> AbsNormalTarget<Target>
    ) {
        downloadTask
            .load(taskId)
            .let {
                block.invoke(it)
            }
            .save()
    }

    /**
     * 获取所有普通下载任务
     * 获取未完成的普通任务列表{@link #getAllNotCompleteTask()}
     * 获取已经完成的普通任务列表{@link #getAllCompleteTask()}
     */
    val allTask: MutableList<DownloadEntity>?
        get() = downloadTask.taskList

    /**
     * filePath:完整路径名（/mnt/sdcard/test.zip）
     * 总是从头开始下载
     */
    fun start(
        url: String, filePath: String,
        httpBuilderTarget: ((build: HttpBuilderTarget) -> Unit)? = null
    ): Long {
        //     customData: String? = null,
        //        m3U8VodOption: M3U8VodOption? = null,/*这里赋值，就代表是m3u8下载*/
        //        m3u8LiveOption: M3U8LiveOption? = null,/*这里赋值，就代表是m3u8下载*/
        val taskBuild = downloadTask
            //读取下载地址
            .load(url)
            //设置文件保存的完整路径
            .setFilePath(filePath)
        httpBuilderTarget?.invoke(taskBuild)
        //创建并启动下载
        return taskBuild.create()
    }

    /**
     * 继续下载
     */
    fun resume(taskId: Long) {
        downloadTask
            .load(taskId)
            .resume()
    }

    /**
     * 恢复所有下载
     * 有bug，待修复
     */
    @Deprecated("有bug，待修复")
    fun resumeAllTask() {
        downloadTask
            .resumeAllTask()
    }

    /**
     * 暂停下载
     */
    fun pause(taskId: Long) {
        downloadTask
            .load(taskId)
            .stop()
    }


    /**
     * 暂停所以下载
     * 有bug，待修复
     */
    @Deprecated("有bug，待修复")
    fun pauseAllTask() {
        downloadTask
            .stopAllTask()
    }

    /**
     * 删除任务
     *
     * @param removeFile {@code true} 不仅删除任务数据库记录，还会删除已经完成的文件,总是删除文件
     * {@code false}如果任务已经完成，只删除任务数据库记录
     */
    fun delete(taskId: Long, removeFile: Boolean = false) {
        downloadTask.load(taskId)
            .cancel(removeFile)
    }

    /**
     * 删除所有下载
     */
    fun deleteAllTask(removeFile: Boolean) {
        downloadTask
            .removeAllTask(removeFile)
    }

    /**
     * 判断任务是否存在
     */
    fun taskExists(url: String): Boolean {
        return downloadTask
            .taskExists(url)
    }

    /**
     * 根据id查询下载任务
     */
    fun getDownloadTask(id: Long?): DownloadEntity? {
        id ?: return null
        return downloadTask.getDownloadEntity(id)
    }

    /**
     * 根据下载地址查询下载任务
     */
    fun getDownloadTask(url: String?): MutableList<DownloadEntity>? {
        url ?: return null
        return downloadTask.getDownloadEntity(url)
    }

    /**
     * 存在就继续下载
     */
    fun startOrResume(
        url: String,
        filePath: String,
        block: ((build: HttpBuilderTarget) -> Unit)? = null
    ): Long {
        val allDownload = allTask
        var taskId: Long? = null
        allDownload?.let { tasks ->
            tasks.forEach {
                if (it.url == url) {
                    taskId = it.id
                    if (it.state != IEntity.STATE_COMPLETE) {
                        resume(it.id)
                    }
                    return@let
                }
            }
        }
        if (taskId == null) {
            taskId =
                start(url, filePath, block)
        }
        return taskId!!
    }

    /**
     * 添加监听器
     * id：数据库id
     */
    fun addListener(id: Long?, listener: Listener) {
        DownloadTaskStatus.listenerMap[id] = listener
    }

    /**
     * 添加监听器
     * lifecycleOwner 生命周期对象，将监听器绑定生命周期
     */
    fun addListener(lifecycleOwner: LifecycleOwner?, listener: LifecycleListener) {
        lifecycleOwner?.lifecycle?.addObserver(listener)
        DownloadTaskStatus.listenerMap[listener.id] = listener
    }


    /**
     * 移除监听器
     */
    fun removeListener(id: Long?) {
        DownloadTaskStatus.listenerMap.remove(id)
    }

    /**
     * 移除监听器
     */
    fun removeListener(lifecycleOwner: LifecycleOwner?, id: Long?) {
        val listener = getListener(id) ?: return
        if (listener is ILifecycleObserver) {
            lifecycleOwner?.lifecycle?.removeObserver(listener)
        }
        DownloadTaskStatus.listenerMap.remove(id)
    }

    /**
     * 移除监听器
     */
    fun removeListener(lifecycleOwner: LifecycleOwner?, listener: LifecycleListener) {
        lifecycleOwner?.lifecycle?.removeObserver(listener)
        DownloadTaskStatus.listenerMap.remove(listener.id)
    }

    /**
     * 查询监听器
     */
    fun getListener(id: Long?): Listener? {
        return DownloadTaskStatus.listenerMap[id]
    }

    /**
     * 带有生命周期的监听，如果设置了监听，在onStop的时候自动移除，onStart的时候自动监听，防止内存泄漏
     * key：下载时为下载链接地址，上传时为文件地址
     * 如果key发生了变化，请移除此监听，添加新的监听
     */
    open class LifecycleListener(val id: Long) : Listener, ILifecycleObserver {
        private var hasListener = false
        override fun onStart() {
            super.onStart()
            start()
        }

        override fun onStop() {
            super.onStop()
            stop()
        }

        private fun stop() {
            //判断当前时候正在监听
            hasListener = getListener(id) != null
            removeListener(id)
        }

        private fun start() {
            //如果退出的时候添加了监听，则自动添加监听
            if (hasListener) {
                hasListener = false
                addListener(id, this)
            }
        }
    }

    /**
     * 监听器
     */
    interface Listener : DownloadTaskListener {

        override fun onWait(task: DownloadTask) {

        }

        override fun onPre(task: DownloadTask) {
        }

        override fun onTaskPre(task: DownloadTask) {
        }

        override fun onTaskResume(task: DownloadTask) {
        }

        override fun onTaskStart(task: DownloadTask) {
        }

        override fun onTaskStop(task: DownloadTask) {
        }

        override fun onTaskCancel(task: DownloadTask) {
        }

        override fun onTaskFail(task: DownloadTask, e: Exception?) {
        }

        override fun onTaskComplete(task: DownloadTask) {
        }

        override fun onTaskRunning(task: DownloadTask) {
        }

        override fun onNoSupportBreakPoint(task: DownloadTask) {
        }
    }
}